/********************************************************************
*	Author: Andy Wu
*	Description: Source file to handle data from the data segments
*	Modifications:
*		-Created on 02/19/2011
*		-added outline of some functions, still a work in progress, still need to 
*			understand how access information in vectors... 02/22/2012
*		-accidentally deleted folder containing this file on 03/04/2012 using WinSCP
*			when trying to move files about and was unable to recover the file;
*			I have continued working from an older copy of the file from about 2
*			weeks back but much of code for getting data from vectors, etc. was lost
*			-03/05/2012
*		-basically started working from scratch again, added outline of functions to handle
*			printing values from test cases that have to be rewritten since the code was
*			lost; also add function to be used to convert data from data segment to binary
*			etc.; functions are mostly either inoperational or not tested; only operational
*			part is the function written to convert string into binary values (though there
*			are still a few bugs), will continue to work on these over the next few weeks
*			but will need a bit of a better understanding of what I'm doing first, will
*			need to know who I will need to pass to and what and how they want me to pass
*			to them before thinking what I will ultimately decide to do...-3/05/2012
*			
**********************************************************************/

#include <iostream>
using std::cerr;
using std::cout;
using std::cin;
using std::endl;

#include <cstdlib> // for exit function

#include "dsegment.h"
#include <cstring>
#include <stdio.h>
#include <sstream>
#include <string>
using std::string;
#include <bitset>
using std::bitset;

//dseg::dseg()	//constructor for dseg class
//	{
//	
//	}

//function where receives pointer for first element of tokenized instruction, the address to beginning of the segment, and the numoflines in segment
//it extracts the instructions out of the vector and converts the code to binary machine code
//afterwards, it calculates and returns memory offset of the segment
//function incomplete;not functional
unsigned int instr_to_mc(vector<string> *a,unsigned int begaddr, unsigned int numoflines)
	{
	unsigned int offset=0;
	
	
	return offset;
	}

/*function to deal with what happens when it scans for and receives a directive*/
//incomplete, not functional
void directives(AssemblerData a)
	{
	unsigned int linenum=0;
	int numofstr=1;
	vector<string> dirdatavec;
	string dirdata;
	char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8,*s9,*s10;
	dirdatavec=a.ret_dir(linenum);
	dirdata=dirdatavec[0];


	//checking for spaces in the data to count the number of individual strings	
	while(dirdata.find (' ')!=string::npos)
		{
		numofstr+=1;
		}

	//getting arguments from the vector and tokenizing them for personal use
	if(numofstr==1)
		{
		scanf(dirdata.c_str(),"%s",s1);
		}
	else if(numofstr==2)
		{
		scanf(dirdata.c_str(),"%s %s",s1,s2);
		}
	else if(numofstr==3)
		{
		scanf(dirdata.c_str(),"%s %s %s",s1,s2,s3);
		}
	else if(numofstr==4)
		{
		scanf(dirdata.c_str(),"%s %s %s %s",s1,s2,s3,s4);
		}
	else if(numofstr==5)
		{
		scanf(dirdata.c_str(),"%s %s %s %s %s",s1,s2,s3,s4,s5);
		}
	else if(numofstr==6)
		{
		scanf(dirdata.c_str(),"%s %s %s %s %s %s",s1,s2,s3,s4,s5,s6);
		}
	else if(numofstr==7)
		{
		scanf(dirdata.c_str(),"%s %s%s %s %s %s %s",s1,s2,s3,s4,s5,s6,s7);
		}
	else if(numofstr==8)
		{
		scanf(dirdata.c_str(),"%s %s %s %s %s %s %s %s",s1,s2,s3,s4,s5,s6,s7,s8);
		}
	else if(numofstr==9)
		{
		scanf(dirdata.c_str(),"%s %s %s %s %s %s %s %s %s",s1,s2,s3,s4,s5,s6,s7,s8,s9);
		}
	else if(numofstr==10)
		{
		scanf(dirdata.c_str(),"%s %s %s %s %s %s %s %s %s %s",s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);
		}
	
	/*operations on how to convert into machine code after comparing directives*/
	if(strcmp(dirdata.c_str(),".align")==0)		/*.align n	 	Align the next datum on a 2^n byte boundary. For example, .align 2 aligns the next value on a word boundary. .align 0 turns off automatic alignment of .half, .word, .float, and .double directives until the next .data or .kdata directive.*/
		{
		
		}
	else if(strcmp(dirdata.c_str(),".ascii")==0)	/*.ascii str 		Store the string in memory, but do not null-terminate it.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".asciiz")==0)	/*.asciiz str	 	Store the string in memory and null-terminate it.*/
		{
		
		}
	else if(strcmp(dirdata.c_str(),".byte")==0)	/*.byte b1,..., bn 	Store the n values in successive bytes of memory.*/
		{
		
		}
	else if(strcmp(dirdata.c_str(),".double")==0)	/*.double d1,..., dn 	Store the n floating point double precision numbers in successive memory locations.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".extern")==0)	/*.extern sym size 	Declare that the datum stored at sym is size bytes large and is a global symbol. This directive enables the assembler to store the datum in a portion of the data segment that is efficiently accessed via register $gp.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".float")==0)	/*	.float f1,..., fn 	Store the n floating point single precision numbers in successive memory locations.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".globl")==0)	/*.globl sym		Declare that symbol sym is global and can be referenced from other files.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".half")==0)	/*.half h1,..., hn 	Store the n 16-bit quantities in successive memory halfwords.*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".space")==0)	/*.space n 		Allocate n bytes of space in the current segment (which must be the data segment in SPIM).*/
		{
			
		}
	else if(strcmp(dirdata.c_str(),".word")==0)	/*.word w1,..., wn 	Store the n 32-bit quantities in successive memory words. SPIM does not distinguish various parts of the data segment (.data, .rdata and .sdata).*/
		{
			
		}
	else	//print out error if not one of above
		{
//		cout<<"Invalid directive"<<endl;
//		exit(1);
		}
	}

/*function to access tokenized data in the vector and return the data*/
/*work in progress, nonfunctional*/
string getdseg(AssemblerData a)
	{
	
//	vector<AssemblyCommands> *dir=a.ret_dir();
	string str;
	
//	for (int i=0; i < dir.size(); i++) /*for loop to scan through the vector*/
		{
		
		/*access directive vector in class AssemblerData and
		 try to look for portion regarding data segment*/
//		if((strcmp(dir.ret_gen(),".data"))||strcmp(dir.ret_gen(),".kdata"))
			{
//			vector<AssemblyCommands> *dir=a.ret_dir();
//			unsigned int ln=dir.ret_ln();
//			if((ln+1)==)	/*trying to retrieve data from vector by looking for information from the nextline of the file*/
				{
					
				}
			}
		}
	return str;
	}

/*function is passed an int and returns 8-bit representation of the int as a string*/
string decnumtobin(int x)
	{
	string binnum;
	bitset<8> binnum_x(x);
	binnum=binnum_x.to_string();
	return binnum;
	}

/*takes string and returns its binary equivalent as type string*/
/*still needs a bit of work, but works for most part*/
string strtobinconv(string str)
	{
	char letter;
	int ascii, len, binary[8], total;
	stringstream ss;

	len = strlen(str.c_str());  /* get the number of characters in str. */
	/* this loop is executed for each letter in the string. */
	for(int i = 0; i<len; i++)
		{
		total = 0;
		letter = str[i]; /* store the first letter */
		ascii = letter;    /* put that letter into an int, so we can see its ASCII number */
		
		//the space and comma are among many characters that do not include the extra zero causing output to be wrong
		if ((ascii!=32)&&(ascii!=36)&&(ascii!=44)&&(ascii!=45)&&(ascii!=46)&&(ascii!=48)
			&&(ascii!=49)&&(ascii!=50)&&(ascii!=51)&&(ascii!=52)&&(ascii!=53)
			&&(ascii!=54)&&(ascii!=55)&&(ascii!=56)&&(ascii!=57)&&(ascii!=58))
			{
			while(ascii>0) /* This while loop converts the ASCII # into binary,
       	                 stores it backwards into the binary array. */
				{
				if((ascii%2)==0)
					{
					binary[total] = 0;
					ascii = ascii/2;
					total++; /* counting number of numbers in the array. */
					}
				else
					{
					binary[total] = 1;
					ascii = ascii/2;
					total++;
					}
				}

			/* this while loop displays the binary code for that letter. */
			binary[total]=0;
			while(total>=0)
				{
				//cout<<binary[total]<<endl;
				ss<<binary[total];
				total--;
				}
			}
		else 
			{
			switch(ascii)
				{
				case 32:	//space
					ss<<"00100000";
					break;
				case 36:	//dollar symbol
					ss<<"00100100";
					break;
				case 44:	//comma
					ss<<"00101100";
					break;
				case 45:	//minus
					ss<<"00101101";
					break;
				case 46:	//period
					ss<<"00101110";
					break;
				case 48:	//0
					ss<<"00110000";
					break;
				case 49:	//1
					ss<<"00110001";
					break;
				case 50:	//2
					ss<<"00110010";
					break;
				case 51:	//3
					ss<<"00110011";
					break;
				case 52:	//4
					ss<<"00110100";
					break;
				case 53:	//5
					ss<<"00110101";
					break;
				case 54:	//6
					ss<<"00110110";
					break;
				case 55:	//7
					ss<<"00110111";
					break;
				case 56:	//8
					ss<<"00111000";
					break;
				case 57:	//9
					ss<<"00111001";
					break;
				case 58:	//colon
					ss<<"00111010";
					break;
				}
			}
		}
	return ss.str();
	}
